window.app = new GE.App('mapContainer', {
    position: [0, 0, 1000],
    lookAt: [0, 0, 1500],
    cameraScrollSpeed: 15,
    minZoom: 3,
    maxZoom: 22,
    ambientLightIntensity: 3,
    ambientLightType: 'ambient',
    useCarpet: true,
    background: "none",
    useDefaultTexture: true, //是否使用瓦片默认纹理
    maxSlopeAngle: 70,
    cameraNear: 0.5,
    isDynamicNear: false,
    isOpenEyeIntersect: true, //开启相机和场景中其他物体的相交检测
    // cameraFov: 30, //相机的视角
    // extraStep:4, //额外加载瓦片的步长，默认是0，这个值越大，加载的范围就越大，但是太大会对性能有影响
    baseLayer: [
        //影像底图
        // {
        //     url: ' https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', //影像底图的url
        //     // url: 'http://115.236.87.26:8848/googleTiles/china_image/{z}/{y}/{x}.jpg',
        //     urlDecimal: true, //影像底图url中的瓦片行列号是否是十进制，true表示十进制，false表示十六进制
        //     tileType: 'image', //影像底图
        //     canNotSelect: false, //true表示该图层不参与射线拾取，false表示图层参与射线拾取
        // }
    ]
});

window.app.options.BackGround.background = "Gradient";
window.app.options.BackGround.backGroundColorA = '#87CEEB'; //#0000FF';
window.app.options.BackGround.backGroundColorB = '#4169E1'; //'#AAAAFF';
window.app.background.set(window.app.options.BackGround);

var originPosition = new GE.Point(0, 0, 0, '4326');
originPosition.toEPSGWeb();
console.log(originPosition);

var counterCount = 0; //电池柜的数量
var doorMeshInstance;
var originBatteryModel;
var doorStatusMap = new Map(); //存储每个门的状态，key值表示instanceId, value值表示门的状态: {isOpen, intervalID, isDoing} //isOpen表示门是否打开，intervalID表示门的动画的定时器，isDoing表示门是否正在做动画
var counterMap = new Map(); //存储每个电池柜的状态，key值表示instanceId, value值表示电池柜的状态: {position, batteryCount, batterys} //position表示电池柜的位置，batteryCount表示电池柜中的电池数量
var batteryCount = 0; //当前要加载电池柜中电池的数量
var batteryDisplayMap = new Map();//存储电池柜中各个电池的canvas，key值：{counterIndex, batteryIndex},counterIndex表示电池柜的编号，batteryIndex表示电池的编号; value值:{canvas, texture}
var screenDisplay = { canvas: null, texture: null }; //屏幕需要的的canvas和texture

function loadCounter(count) { //加载电池柜
    counterCount = count;
    let modelPosition = [0, 0, 0, '3857'];
    loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/DCG_gui.FBX', 'fbx', modelPosition, batteryCounterCallback); //加载电池柜
    loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/DCG_men(1).FBX', 'fbx', [0, 0, 105 * 2, '3857'], batteryCounterDoorCallback); //加载电池柜的门
}

function loadBatteryInCounter(counterIndex, count) { //加载电池柜中的电池
    if (counterIndex >= counterCount) {
        return;
    }
    let counterMsg = counterMap.get(counterIndex);
    if (!counterMsg) { //如果机柜还没有加载完成，则等待500毫秒后再次加载
        setTimeout(() => {
            loadBatteryInCounter(counterIndex, count);
        }, 500);
        return;
    }
    if (counterMsg.batterys) {
        counterMsg.batterys.forEach(element => {
            app.remove(element);
        });
    }

    let counterPosition = counterMsg.position;
    counterMsg.batteryCount = count;
    batteryCount = count > 16 ? 16 : count;
    // loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/Dianchi.FBX', 'fbx', counterPosition, batteryCallback); //加载电池

    let originMesh = originBatteryModel.children[0].children[0];
    originMesh.updateMatrixWorld(true);
    let originMatrix = originMesh.matrix; //.matrixWorld;

    let startZ = counterPosition[2] + 20;
    let offsetZ = 48;
    let startX = counterPosition[0] - 30;
    let offsetX = 20;
    let startY = counterPosition[1] - 25;
    let batteryIndex = 0; // 初始化计数器
    counterMsg.batterys = [];
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (batteryIndex >= batteryCount) {
                break;
            }
            let curMatrix = originMatrix.clone();
            // curMatrix.setPosition(new GE.three.Vector3(model.position.x, model.position.y, model.position.z));

            let rotateMatrix = new GE.three.Matrix4();
            rotateMatrix.makeRotationX(90 / 180 * Math.PI);
            curMatrix.multiply(rotateMatrix);

            let newPosition = new GE.three.Vector3(startX + j * offsetX, startY, startZ + (offsetZ) * i);
            curMatrix.setPosition(newPosition);

            let materials = [];
            for (let i = 0; i < originMesh.material.length; i++) {
                let curMaterial = originMesh.material[i];
                if (curMaterial.name == 'xianshiping_02') {
                    curMaterial = curMaterial.clone();

                    //创建一个canvas
                    let drawingCanvas = document.createElement('canvas');
                    drawingCanvas.width = 128;
                    drawingCanvas.height = 128;

                    curMaterial.map = new GE.three.CanvasTexture(drawingCanvas);
                    let batteryKey = { counterIndex: counterIndex, batteryIndex: batteryIndex };
                    let batteryKeyStr = JSON.stringify(batteryKey);
                    batteryDisplayMap.set(batteryKeyStr, { canvas: drawingCanvas, texture: curMaterial.map });
                }
                materials.push(curMaterial);
            }

            let curBatteryMesh = new GE.three.Mesh(originMesh.geometry, materials);
            curBatteryMesh.matrix = curMatrix;

            // 告诉three.js不要自动更新matrix，因为我们直接设置了matrix
            curBatteryMesh.matrixAutoUpdate = false;
            // 更新mesh的matrixWorld以反映新的变换
            curBatteryMesh.updateMatrixWorld(true);

            curBatteryMesh.setClick = function (e) {
                let butteryMesh = e.object;
                let matrix = butteryMesh.matrix;
                let dragDistance = 50; //电池被点中后，在Z轴上移动的距离
                if(!butteryMesh['isDragOut']){
                    let newPosition = new GE.three.Vector3(matrix.elements[12], matrix.elements[13] - dragDistance, matrix.elements[14]);
                    matrix.setPosition(newPosition);
                    butteryMesh['isDragOut'] = true;
                }else{
                    let newPosition = new GE.three.Vector3(matrix.elements[12], matrix.elements[13] + dragDistance, matrix.elements[14]);
                    matrix.setPosition(newPosition);
                    butteryMesh['isDragOut'] = false;
                }
              
                butteryMesh.matrixAutoUpdate = false;
                butteryMesh.updateMatrixWorld();
            }

            app.add(curBatteryMesh);
            counterMsg.batterys.push(curBatteryMesh);

            window.app.camera.addIntersectObjWithEye(curBatteryMesh); //该模型和相机做相交检测，避免穿透

            batteryIndex++;
        }
    }
}

loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/Dianchi.FBX', 'fbx', [0, 0, 0, '3857'], function (model) {
    originBatteryModel = model;
}); //加载电池模型

loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/DYXT.FBX', 'fbx', [80, 0, 0, '3857'], defaultCallback);
loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/XDCAQYWZNGLXT(2).FBX', 'fbx', [160, 0, 0, '3857'], defaultCallback);

function loadModel(url, type, point, callback) {
    let model = new GE.OverLay({
        type: type,
        url: url,
        dracoPluginUrl: 'http://localhost:9000/examples/resources/plugin/draco/',
        position: point, //[0, 0, 20],
        // changeEmissive: true,
        gltfUpAxis: 'Y',
        scale: [1, 1, 1],
        // rotation: [90, 0, 0],
        success: callback
    });
}

function defaultCallback(model) {
    app.add(model);
    for (let i = 0; i < model.children[0].children[0].material.length; i++) {
        let curMaterial = model.children[0].children[0].material[i];
        if (curMaterial.name == 'xianshiping_01') {
            //创建一个canvas
            let drawingCanvas = document.createElement('canvas');
            drawingCanvas.width = 1024;
            drawingCanvas.height = 512;

            curMaterial.map = new GE.three.CanvasTexture(drawingCanvas);
            screenDisplay.canvas = drawingCanvas;
            screenDisplay.texture = curMaterial.map;
        }
    }
    window.app.camera.addIntersectObjWithEye(model); //该模型和相机做相交检测，避免穿透
}

function batteryCounterDoorCallback(model) {
    let instanceCount = counterCount;
    let originMesh = model.children[0].children[0];
    originMesh.updateMatrixWorld(true);
    let originMatrix = originMesh.matrix; //.matrixWorld;
    doorMeshInstance = new GE.three.InstancedMesh(originMesh.geometry, originMesh.material, instanceCount);

    let startX = model.position.x + 40;
    let offsetX = -80;
    let startZ = model.position.z - 210; //116
    let startY = model.position.y - 50;
    let instaceIndex = 0;
    let matrixArray = [];
    for (let i = 0; i < instanceCount; i++) {
        let curMatrix = originMatrix.clone();

        let rotateMatrix = new GE.three.Matrix4();
        rotateMatrix.makeRotationX(90 / 180 * Math.PI);
        curMatrix.multiply(rotateMatrix);

        let newPosition = new GE.three.Vector3(startX + i * offsetX, startY, startZ);
        curMatrix.setPosition(newPosition);
        doorMeshInstance.setMatrixAt(instaceIndex, curMatrix);
        matrixArray.push(curMatrix);

        doorMeshInstance.updateMatrix();

        doorStatusMap.set(instaceIndex, { isOpen: false, intervalID: null, isDoing: false });

        instaceIndex++;
    }

    doorMeshInstance.instanceMatrix.needsUpdate = true;
    app.add(doorMeshInstance);

    doorMeshInstance.setClick = function (e) {
        let instanceId = e.objs.instanceId;
        let doorMsg = doorStatusMap.get(instanceId);
        let isOpen = doorMsg.isOpen;
        if (doorMsg.isDoing) {
            return;
        }

        if(isOpen){ //如果关闭电池柜的门，需要把该电池柜中的电池都放到原始位置
            let counterMsg = counterMap.get(instanceId);
            if( counterMsg.batterys ){
                counterMsg.batterys.forEach((butteryMesh) => { 
                    if(butteryMesh['isDragOut']){
                        let dragDistance = 50;
                        let matrix = butteryMesh.matrix;
                        let newPosition = new GE.three.Vector3(matrix.elements[12], matrix.elements[13] + dragDistance, matrix.elements[14]);
                        matrix.setPosition(newPosition);
                        butteryMesh.matrixAutoUpdate = false;
                        butteryMesh.updateMatrixWorld();
    
                        butteryMesh['isDragOut'] = false;
                    }
                })
            }
        }
       

        let lastIntervalID = doorMsg.intervalID;
        if (lastIntervalID) {
            clearInterval(lastIntervalID);
        }

        let curRotateZ = 0;
        let intervalId = setInterval(() => { //门开合动画
            doorMsg.intervalID = true;

            if (isOpen == false) {
                curRotateZ--;
            } else {
                curRotateZ++;
            }

            let rotateMatrix = new GE.three.Matrix4();
            rotateMatrix.makeRotationZ(curRotateZ / 180 * Math.PI);

            let meshMatrix = matrixArray[instanceId].clone();
            meshMatrix.multiply(rotateMatrix);
            doorMeshInstance.setMatrixAt(instanceId, meshMatrix);

            doorMeshInstance.instanceMatrix.needsUpdate = true;
            doorMsg.isOpen = !isOpen;
            doorMsg.intervalID = intervalId;
            doorMsg.isDoing = true;

            if (!isOpen && curRotateZ <= -90) {
                clearInterval(intervalId);
                matrixArray[instanceId] = meshMatrix;
                doorMsg.isDoing = false;
            } else if (isOpen && curRotateZ >= 90) {
                clearInterval(intervalId);
                matrixArray[instanceId] = meshMatrix;
                doorMsg.isDoing = false;
            }
        }, 10);
        doorMsg.intervalID = intervalId;
    }

    window.app.camera.addIntersectObjWithEye(doorMeshInstance); //该模型和相机做相交检测，避免穿透
}

function batteryCounterCallback(model) {
    let instanceCount = counterCount;
    let originMesh = model.children[0].children[0];
    originMesh.updateMatrixWorld(true);
    let originMatrix = originMesh.matrix; //.matrixWorld;
    let instanceMesh = new GE.three.InstancedMesh(originMesh.geometry, originMesh.material, instanceCount);

    let startX = model.position.x;
    let offsetX = -80;
    let startZ = model.position.z + 0; //116
    let startY = model.position.y;
    let instaceIndex = 0; // 初始化计数器
    for (let i = 0; i < instanceCount; i++) {
        let curMatrix = originMatrix.clone();

        let rotateMatrix = new GE.three.Matrix4();
        rotateMatrix.makeRotationX(90 / 180 * Math.PI);
        curMatrix.multiply(rotateMatrix);

        let newPosition = new GE.three.Vector3(startX + i * offsetX, startY, startZ);
        curMatrix.setPosition(newPosition);
        instanceMesh.setMatrixAt(instaceIndex, curMatrix);

        instanceMesh.updateMatrix();

        let batteryPosition = [newPosition.x, newPosition.y, newPosition.z - 0, '3857']; //116
        let counterMsg = { position: batteryPosition, batteryCount: 0 };
        counterMap.set(instaceIndex, counterMsg);

        instaceIndex++;
        // loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/Dianchi.FBX', 'fbx', batteryPosition, batteryCallback); //加载电池

        // loadModel('http://localhost:9000/examples/resources/fbx/电池测试模型/模型/DCG_men.FBX', 'fbx',  [startX + i * offsetX, 0, 105*2, '3857'], defaultCallback); //加载电池柜的门
    }

    instanceMesh.instanceMatrix.needsUpdate = true;
    app.add(instanceMesh);

    window.app.camera.addIntersectObjWithEye(instanceMesh); //该模型和相机做相交检测，避免穿透
}

function batteryCallback(model) {
    let instanceCount = batteryCount;
    window.app.camera.addIntersectObjWithEye(model); //该模型和相机做相交检测，避免穿透
}

function traverseMeshes(mesh, callback) {
    // 对当前mesh执行回调
    if (mesh.type == 'Mesh') {
        callback(mesh);
    }
    // 遍历子节点
    mesh.children.forEach(child => {
        if (child.isObject3D) {
            traverseMeshes(child, callback);
        }
    });
}

function setEmmisive(material) {
    if (!material.emissive) {
        return;
    }
    material.emissive.set(1, 1, 1);
    material.emissiveIntensity = 1;
    material.emissiveMap = material.map;
}

addPolygon(); //添加多边形

function addPolygon() {
    // let img = 'http://192.168.2.100:8702/resources/1b8b2fcb26b020120aebfac57779e06a/images/img_logo.39362dc1.png'; //'/examples/assets/img_logo.39362dc1.png';
    let pointArray = [ //3857表示web墨卡托坐标系，4326表示经纬度坐标
        new GE.Point(-1, 1, 0, '3857'),
        new GE.Point(-1, -1, 0, '3857'),
        new GE.Point(1, -1, 0, '3857'),
        new GE.Point(1, 1, 0, '3857')
    ];
    let polygonData = {
        pointArray: pointArray,  //多边形的顶点数组
        // textureImg: img, //贴在多边形上的图片
        alphaValue: 0.3,  //透明值
        color: '#A9A9A9',//'#6495ED', //'#D3D3D3', // 多边形的颜色
        transparent: true,
        depthTest: true
    };
    let polygon = new GE.Polygon(polygonData);
    app.add(polygon);

    let testVector = new GE.three.Vector3(0, 0, 0);

    let oldPosition = polygon.position.clone();
    polygon.position.set(0, 0, 0);
    let polygonScale = 2000;
    polygon.scale.set(polygonScale, polygonScale, 1);
    polygon.position.set(oldPosition.x * polygonScale, oldPosition.y * polygonScale, oldPosition.z);
    polygon.updateMatrix();
    polygon.updateMatrixWorld(true);
    polygon.updateWorldMatrix(true, true);

    // window.app.mouse.addHoverObject(polygon); //为该模型添加鼠标悬停的功能
    // window.app.mouse.removeHoverObject(polygon); //为该模型移除鼠标悬停的功能
}
